home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SampleDriver.c
-
- Contains: Driver for Sample USB device
-
- Version: xxx put version here xxx
-
- Copyright: © 1997-1998 by Apple Computer, Inc., all rights reserved.
-
-
- Writers:
-
- (CJK) Craig Keithley
-
- Change History (most recent first):
-
- */
-
- #include <Types.h>
- #include <Devices.h>
- #include <processes.h>
- #include <DriverServices.h>
- #include <USB.h>
-
- #include "SampleDriver.h"
- #include "hex2c.h"
-
- extern INTEL_HEX_RECORD bulktest[];
-
- usbSamplePBStruct mySamplePB;
-
- void InitParamBlock(USBDeviceRef theDeviceRef, USBPB * paramblock)
- {
- paramblock->usbReference = theDeviceRef;
- paramblock->pbVersion = kUSBCurrentPBVersion;
- paramblock->usbStatus = noErr;
- paramblock->usbBuffer = nil;
- paramblock->usbActCount = 0;
- paramblock->usbReqCount = 0;
- paramblock->usbFlags = 0;
- paramblock->usbOther = 0;
- }
-
-
-
- Boolean immediateError(OSStatus err)
- {
- return((err != kUSBPending) && (err != noErr) );
- }
-
- void InitiateTransactionProc(USBPB *pb)
- {
- register usbSamplePBStruct *pSamplePB;
- OSStatus myErr;
-
- pSamplePB = (usbSamplePBStruct *)(pb);
- pSamplePB->transDepth++;
- if (pSamplePB->transDepth < 0)
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth < 0 (initiation)", pSamplePB->pb.usbRefcon );
- }
-
- if (pSamplePB->transDepth > 1)
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth > 1 (initiation)", pSamplePB->pb.usbRefcon );
- }
-
- switch(pSamplePB->pb.usbRefcon & ~kRetryTransaction)
- {
- case kFindInterface:
- InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
- pSamplePB->pb.usb.cntl.WIndex = 0;
- pSamplePB->pb.usb.cntl.WValue = 0;
- pSamplePB->pb.usbClassType = 0xff;
- pSamplePB->pb.usbSubclass = 0xff;
- pSamplePB->pb.usbProtocol = 0xff;
- pSamplePB->pb.usbRefcon |= kCompletionPending;
- pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBFindNextInterface(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pSamplePB->pb.usbReference, kUSBInternalErr, kDriverName": USBFindNextInterface (immediate error)", myErr);
- pSamplePB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kOpenDevice:
- InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
- pSamplePB->pb.usb.cntl.WValue = pSamplePB->configurationNumber;
- pSamplePB->pb.usbRefcon |= kCompletionPending;
-
- pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- myErr = USBOpenDevice(pb);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pSamplePB->pb.usbReference, kUSBInternalErr, kDriverName": USBOpenDevice (immediate error)", myErr);
- pSamplePB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kAssert8051Reset:
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Asserting 8051 Reset", pSamplePB->deviceRef);
- pSamplePB->writeBuffer[0] = 0x01;
- myErr = SampleWrite(&pSamplePB->pb, k8051_USBCS, 1, pSamplePB->writeBuffer);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Assert 8051 Reset - immediate error", myErr);
- }
- break;
-
- case kDownload8051Firmware:
- USBExpertStatus(bulktest[pSamplePB->recordnum].Address, kDriverName": Downloading record", pSamplePB->recordnum);
- myErr = SampleWrite(&pSamplePB->pb, bulktest[pSamplePB->recordnum].Address, bulktest[pSamplePB->recordnum].Length, bulktest[pSamplePB->recordnum].Data);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Download Firmware - immediate error", myErr);
- }
- break;
-
- case kNegate8051Reset:
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Negating 8051 Reset", pSamplePB->deviceRef);
- pSamplePB->writeBuffer[0] = 0x00;
- myErr = SampleWrite(&pSamplePB->pb, k8051_USBCS, 1, pSamplePB->writeBuffer);
- if(immediateError(myErr))
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Negate 8051 Reset - immediate error", myErr);
- }
- break;
-
- default:
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": Transaction initiated with bad refcon value", pSamplePB->pb.usbRefcon);
- pSamplePB->pb.usbRefcon = kUndefined + kReturnFromDriver;
- break;
- }
-
- // At this point the control is returned to the system. If a USB transaction
- // has been initiated, then it will call the Complete procs
- // (below) to handle the results of the transaction.
- }
-
-
- void TransactionCompletionProc(USBPB *pb)
- {
- register usbSamplePBStruct *pSamplePB;
- unsigned char * errstring;
- USBPipeState pipeState;
-
- pSamplePB = (usbSamplePBStruct *)(pb);
- pSamplePB->transDepth--;
- if (pSamplePB->transDepth < 0)
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth < 0 (completion)", pSamplePB->pb.usbRefcon );
- }
-
- if (pSamplePB->transDepth > 1)
- {
- USBExpertFatalError(pSamplePB->deviceRef, kUSBInternalErr, kDriverName": transDepth > 1 (completion)", pSamplePB->pb.usbRefcon );
- }
-
- if(pSamplePB->pb.usbStatus != noErr) // was there an error?
- {
- switch(pSamplePB->pb.usbRefcon & 0x0fff) // yes, so show where the error occurred
- {
- case kFindInterface: errstring = kDriverName": Error during kFindInterface"; break;
- case kOpenDevice: errstring = kDriverName": Error during kOpenDevice"; break;
- case kAssert8051Reset: errstring = kDriverName": Error during kAssert8051Reset"; break;
- case kDownload8051Firmware: errstring = kDriverName": Error during kDownload8051Firmware"; break;
- case kNegate8051Reset: errstring = kDriverName": Error during kNegate8051Reset"; break;
- default: errstring = kDriverName": Error occurred, but state is unknown"; break;
- };
- USBExpertFatalError(pSamplePB->deviceRef, pSamplePB->pb.usbStatus, errstring, (pSamplePB->pb.usbRefcon & 0x0fff));
-
- pSamplePB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver); // set up to retry the transaction
- pSamplePB->pb.usbRefcon |= kRetryTransaction;
- pSamplePB->retryCount--;
-
- if ((!pSamplePB->retryCount) || (pSamplePB->pb.usbStatus == kUSBAbortedError)) // have we exhausted the retries?
- { // or received an abort?
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Pipe abort or unable to recover from error", pSamplePB->deviceRef);
- pSamplePB->pb.usbRefcon = kReturnFromDriver; // if so, just exit.
- }
- else // if it didn't abort and there's retries left, then...
- {
- if (pSamplePB->pipeRef) // check if the pipe is open.
- {
- USBGetPipeStatusByReference(pSamplePB->pipeRef, &pipeState); // yes, so what it's state?
- if (pipeState != kUSBActive) // if it's not active, try to clear it. It might be stalled...
- {
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Pipe is open and stalled, clearing stall...", pSamplePB->deviceRef);
- USBClearPipeStallByReference(pSamplePB->pipeRef);
- }
- }
- }
- }
- else
- {
- pSamplePB->pb.usbRefcon &= ~kRetryTransaction;
- pSamplePB->retryCount = kSampleRetryCount;
- }
-
- if (pSamplePB->pb.usbRefcon & kCompletionPending)
- {
- pSamplePB->pb.usbRefcon &= ~(kCompletionPending + kReturnFromDriver);
- switch(pSamplePB->pb.usbRefcon)
- {
- case kFindInterface:
- if ((pSamplePB->pb.usbClassType == 0xff) &&
- (pSamplePB->pb.usbSubclass == 0xff) &&
- (pSamplePB->pb.usbProtocol == 0xff))
- {
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Found Interface (0 endpoints)", pSamplePB->deviceRef);
- pSamplePB->interfaceNumber = pSamplePB->pb.usb.cntl.WIndex;
- pSamplePB->configurationNumber = pSamplePB->pb.usb.cntl.WValue;
- pSamplePB->pb.usbRefcon = kOpenDevice;
- }
- else
- {
- pSamplePB->pb.usbRefcon = kReturnFromDriver;
- }
- break;
-
- case kOpenDevice:
- pSamplePB->pb.usbRefcon = kAssert8051Reset;
- break;
-
- case kAssert8051Reset:
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Reset asserted", pSamplePB->deviceRef);
- pSamplePB->recordnum = 0;
- pSamplePB->pb.usbRefcon = kDownload8051Firmware;
- break;
-
- case kDownload8051Firmware:
- pSamplePB->recordnum++;
- if (bulktest[pSamplePB->recordnum].Type)
- {
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": 8051 Firmware download complete", pSamplePB->deviceRef);
- pSamplePB->pb.usbRefcon = kNegate8051Reset;
- }
- else
- {
- pSamplePB->pb.usbRefcon = kDownload8051Firmware;
- }
- break;
-
- case kNegate8051Reset:
- USBExpertStatus(pSamplePB->deviceRef, kDriverName": Reset negated", pSamplePB->deviceRef);
- pSamplePB->pb.usbRefcon = kReturnFromDriver;
- break;
-
-
- }
- }
- if (!(pSamplePB->pb.usbRefcon & kReturnFromDriver))
- InitiateTransactionProc(pb);
- }
-
- OSStatus SampleWrite(USBPB *pb, UInt32 driverAddress, UInt32 count, UInt8 writeBuffer[])
- {
- register usbSamplePBStruct *pSamplePB;
- OSStatus myErr = kUSBNoErr;
-
- pSamplePB = (usbSamplePBStruct *)(pb);
-
- InitParamBlock(pSamplePB->deviceRef, &pSamplePB->pb);
- pSamplePB->pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBVendor, kUSBDevice);
-
- pSamplePB->pb.usb.cntl.BRequest = 0xa0;
- pSamplePB->pb.usb.cntl.WValue = driverAddress;
- pSamplePB->pb.usb.cntl.WIndex = 0x00;
-
- pSamplePB->pb.usbBuffer = (Ptr)&writeBuffer[0];
- pSamplePB->pb.usbReqCount = count;
-
- pSamplePB->pb.usbCompletion = (USBCompletion)TransactionCompletionProc;
- pSamplePB->pb.usbRefcon |= kCompletionPending;
-
- myErr = USBDeviceRequest(&pSamplePB->pb);
- return myErr;
- }
-
-
-